import { toRaw, unref, isReactive, isRef } from "vue"

// vue 事件对象
// a-textarea 事件对象
export const isVueObject = (data: any) => {
  return isObject(data) || isFocusEvent(data) || isInputEvent(data)
}
export const isFocusEvent = (data: any) => {
  const type = Object.prototype.toString.call(data)
  return type === "[object FocusEvent]"
}
// a-input 事件对象
export const isInputEvent = (data: any) => {
  const type = Object.prototype.toString.call(data)
  return type === "[object isInputEvent]"
}
export function isString<T>(data: T): boolean {
  const type = Object.prototype.toString.call(data)
  return type === "[object String]"
}
export function isBoolean<T>(data: T): boolean {
  const type = Object.prototype.toString.call(data)
  return type === "[object Boolean]"
}
export function isNumber<T>(data: T): boolean {
  const type = Object.prototype.toString.call(data)
  return type === "[object Number]"
}
export function isArray<T>(data: T): boolean {
  const type = Object.prototype.toString.call(data)
  return type === "[object Array]"
}
export function isFunction<T>(data: T): boolean {
  const type = Object.prototype.toString.call(data)
  return type === "[object Function]"
}
export function isObject<T>(data: T): boolean {
  const type = Object.prototype.toString.call(data)
  return type === "[object Object]"
}
export function isNull<T>(data: T): boolean {
  const type = Object.prototype.toString.call(data)
  return type === "[object Null]"
}
export function isUndefined<T>(data: T): boolean {
  const type = Object.prototype.toString.call(data)
  return type === "[object Undefined]"
}

export function isValidUrl (path:string):boolean {
  if (!path) return false
  return /^(https?:)/.test(path)
}

export function isEmptyObject<T extends object>(data: T): boolean {
  if (isNull(data)) return true
  if (!isObject(data)) return false
  return Object.keys(data).length === 0
}

export function isKeyExist<T extends object>(data: T, key: string): boolean {
  if (!isObject(data)) return false
  return Object.prototype.hasOwnProperty.call(data, key)
}
export const isObjectOwnProperty = (data: any, key: string) => {
  if (!isObject(data)) return false
  return Object.prototype.hasOwnProperty.call(data, key)
}
export const isFile = (data: any) => {
  const type = Object.prototype.toString.call(data)
  return type === "[object File]"
}
export const isDate = (data: any) => {
  const type = Object.prototype.toString.call(data)
  return type === "[object Date]"
}
export const isBlob = (data: any) => {
  const type = Object.prototype.toString.call(data)
  return type === "[object Blob]"
}
export const isArrayBuffer = (data: any) => {
  const type = Object.prototype.toString.call(data)
  return type === "[object ArrayBuffer]"
}

export const isSameValue = (pre: any, cur: any) => {
  pre = parseToVueValue(pre)
  cur = parseToVueValue(cur)
  if (!isString(pre)) {
    pre = JSON.stringify(pre)
  }
  if (!isString(cur)) {
    cur = JSON.stringify(cur)
  }
  return pre === cur
}

export const parseToVueValue = (data: any): any => {
  if (isReactive(data)) {
    data = toRaw(data)
    return parseToVueValue(data)
  }
  if (isRef(data)) {
    data = unref(data)
    return parseToVueValue(data)
  }
  return data
}

export function parseJsonString(data: string): object|null {
  let obj = null
  if (isString(data)) {
    try {
      obj = JSON.parse(data)
    } catch (error) {
      obj = null
    }
  } else if (isObject(data)) {
    obj = data
  }
  return obj
}
